【第1380期】如何像程序员般思考 —— 蕴含在问题解决中的经验
前言
8月份结束了。解决问题都是有一套框架或思路的,有某方法论支撑。今日早读文章由@mingxing47翻译授权分享。
正文从这开始~~
如果你对编程感兴趣,那么你之前可能会听说过这样的 一句话:
“每个人都应该学习编程,因为它会教你如何思考。” —— 史蒂夫·乔布斯
你可能还想知道,像程序员一样思考到底意味着什么?同时,要怎么样才能做到呢?
从本质上讲,像程序员般思考是一种更加有效的解决问题的方法。
通过这篇文章,我的目的是教会你用那样的方式去思考问题。
到最后,你就会更加清楚地知道,要通过哪些步骤才能成为一个更好的难题终结者。
这件事为什么很重要?
解决问题是最根本的元技能。
我们所有人都会遇到或大或小的各种各样的难题。而很多时候,我们如何去解决这些问题却显得,可以说…很随机。
除非你有一套解决问题的体系,否则如下很可能就是你“解决”问题的方法(这也正是我编程之初常常走的歧途):
尝试某种解决方案。
如果这种解决方案不凑效,那么换另外一个进行尝试。
如果另一种还是不凑效,那么不断重复步骤 2,直到走大运恰好碰到解决这个问题的方法。
你看,某些时候可能你很走运,能够把问题解决。但这却是解决问题中最最糟糕的方法。同时,这对你的时间造成了巨大浪费。
最好的方法包含了以下的两个方面:a)拥有一套解决问题的框架;b)不断练习实践这套框架。
“几乎所有的雇主都把解决问题的能力放在首位。
解决问题的能力几乎是所有雇主一致追寻的最重要的品质,甚至比精通编程语言、调试和系统设计更为重要。
证明计算思维或者说分解大型复杂问题的能力,对于一份工作来说,至少与其所需的基本技术技能一样有价值(就算不是更有价值的话)。” —— Hacker Rank (2018 年开发者技能报告)
拥有一套解决问题的框架
为了找到正确的框架,我遵循了蒂姆·费里斯(Tim Ferriss)关于学习的书《4 小时厨师》(the 4-Hour Che) 中的建议。
这个建议让我采访了两位真正令人印象深刻的人:C. Jordan Ball(在 Coderbyte 65,000+ 用户中排名第一或者第二),以及 V. Anton Spraul(书籍 “像程序员般思考:创造性解决难题导论” 的作者)。
我问了他们相同的问题,你猜猜结果如何?他们的答案基本是一致的!
很快,你也会认识到这些答案。
作者注:这并不意味着他们用相同的方法去做每一件事。每个人都是不同的,你和他们也是不同的。但如果你遵循了我们都认同的好的原则,以此开始,你会走得更远更快。
“我看到的新手程序员犯的最大的错误就是专注于学习编程语言语法而不是去学习如何解决问题。” —— V. Anton Spraul
那么,遇到新问题时该怎么做呢?
下面就是解决问题的一些步骤:
1. 理解问题
准确地理解问题所问的点是什么。绝大多数的难题,仅难在你不能理解这些问题(这就是为什么要把理解问题放在第一步的原因)。
如何知道你已经理解了一个问题?当你能用语言描述它的时候就真的理解了。
你记忆中是否有这样一个场景,当你被困在一个问题中时,你开始解释它,然后突然之间,你发现了之前从来没有考虑过的逻辑漏洞?
绝大多数的程序员都应该对这种感觉深有体会。
这就是为什么你要把你的问题写下来、画个图或者告诉他人的原因(另外一件事是…有些程序员会使用小黄鸭调试法来解决问题)。
“如果你无法简单地解释清楚某件事,你就还没有弄懂它。” —— Richard Feynman
2. 做出计划
在没有计划之前千万不要一头扎入问题的解决当中(除非你希望能够蒙混过关)。一定要做好计划!
如果你无法写下做事情的确切步骤,那么什么都帮不了你。
在编程中,这意味着不要一开始就强行暴力破解。一定要先给你大脑一些时间来分析问题和处理信息。
为了获得一个好的解决问题计划,先回答一下如下问题:
“在已有输入 X 的前提下,如果要得到返回值 Y,将要进行哪些必要的步骤?”
作者注:程序员们有一种很棒的工具来解决这个问题…那就是注释!
3. 划分问题单元
注意了,这是所有步骤中最最重要的。
不要尝试去解决一个大的问题。这样做你肯定会哭的。
相反,应该把大问题分解成多个更容易解决的的子问题。
然后,对这些子问题各个击破。从最简单的问题开始吧。最简单的问题意味着你知道问题的答案(或者至少更为靠近答案)。
除此之外,最简单的问题还意味着这个子问题的解决并不依赖于其他问题的解决。
一旦你把每一个子问题都解决了,然后就把每一个小点连接起来。
串联起你的每一个“子方案”将会让你获得最终的原始问题的解决方案。祝贺你,你已经解决了问题!
这种解决问题的技术是所有问题解决的基石。牢牢记住它(如果有必要,请再次阅读这一步)。
“如果我能教给每个新手程序员一个解决问题的技巧,那就是‘减少问题的技术’。
例如,如果你是一个新程序员,然后你被要求去写一个程序,读取 10 个数字,然后算出哪个数字是第三大的。对于一个全新的程序员来说,这可能是一项艰巨的任务,尽管它只需要基本的编程语法。
如果你陷入困境,你应该把问题简化。先不考虑找第三大的数,如果你去找最大的数你该如何做?还是太困难?那如果要从三个数字中找到最大的你该怎么做呢?如果从两个数字中寻找呢?
不断简化问题直到你能写出解决方案。然后稍微把问题进行扩展,并写下相应的解决方法,不断扩展下去直到源问题被解决。” —— V. Anton Spraul
4. 陷入问题当中?
现在,你可能正坐在那里想到:“嘿,Richard… 这方法很酷,但是如果我卡住了,然后连子问题都无法解决该怎么办?”
首先呢,进行一下深呼吸。其次,这件事是公平的。
不要担心,朋友。这种情况会在每个人身上发生!
不同的是最好的程序员/问题解决者对 bugs 或错误更感兴趣而不是恼怒。
事实上,当不幸面临难题时,这里有三件事可以尝试:
调试: 一步一步检查你的解决方案,然后去试图寻找到底那里出错了。程序员们把这件事称为调试(事实上,这事全是调试器做的)。
“调试的艺术在于找出你真正告诉你的程序去做的事情,而不是你所认为你已经告诉了你的程序去做的事情。” —— Andrew Singer
重新考虑: 后退一步。从另外一个角度来看待这个问题。是否有可以抽象成更一般的方法?
“有时候我们迷失在问题的细节里,而忽略了能在更一般层面上解决问题的通用方法。 […]
当然,最经典的例子是求连续自然数和, 1 + 2 + 3 + … + n,非常年轻的高斯很快认识到答案是简单的 n(n+1)/2,这样就不用去做加法了。” —— C. Jordan Ball
作者注:另外一种重新评估的方式是重新开始。删除所有内容,用全新的眼光重新开始。我是认真的,你会惊讶于这是多么的有效。
搜索:啊哈,你没有读错,好好去搜索一下。无论你遇到什么样的问题,很可能已经有人解决过了。去找到那个人或者找到那种解决方法。事实上,即使你解决了问题,你也可以再去调查一下!(你可以从其他人的解决方案中学到很多的东西。)
注意:不要去寻找解决一个大问题的方法。只去寻找解决子问题的方案。这是为什么呢?因为除非你努力(哪怕是一点点),否则你什么都学不到。如果你什么都没有学到,你就是在浪费时间。
不断实践练习这套框架
不要期望仅仅一个星期之后就能变得很棒。如果你想成为一个好的问题解决者,那就多去解决一些问题吧!
练习、练习、再练习。迟早你会意识到“这个问题可以通过 <在这里插入概念> 轻松解决”。
如何去练习呢?这里有很多的选择!
象棋谜题、数学难题、数独、围棋、大富翁、电子游戏、加密猫,等等等等。
事实上,成功人士的一个普遍模式是他们有着不断练习“微观解决问题”的习惯。例如,彼得·泰尔 (Peter Thiel) 通过下棋,埃隆·马斯克 (Elon Musk) 通过玩电子游戏来进行练习一样。
“拜伦•里夫斯 (Byron Reeves) 说,‘如果你想知道未来三到五年的企业领导是什么样的,那就看看网络游戏正在发生什么吧。’”
快进到今天。埃隆·马斯克(Elon Musk)、雷德·霍夫曼(Reid Hoffman)、马克·扎克伯格(Mark Zuckerberg)和其他许多人都表示,游戏是他们成功建立公司的基石。” —— Mary Meeker(2017年互联网趋势报告)
这是否意味着你应该只玩电子游戏?并不是这样。
但是电子游戏到底是关于什么的呢?没错,就是问题解决!
所以,你应该做的是找到能够练习的机会。可以是能让你解决很多小问题的东西(理想情况下,这应该是你喜欢的东西)。
例如,我喜欢编程挑战。每天,我都试图解决至少一个挑战(通常在 Coderbyte 上)。
正如我所说,所有的问题都有相似的模式。
结论
以上就是全部内容!
直至目前,你已经更好地了解了“像程序员般思考”究竟意味着什么。
你也知道了解决问题是一种难以置信的技能(元技能)。
如果这还不够,请注意,你还知道了要练习解决问题的技巧该做些什么!
啧啧啧… 听起来很酷,对吧?
最后,祝你遇到很多问题。
你没有读错,就是祝你遇到更多的问题。因为至少现在你知道怎么去解决问题了!(同时,你将会知道,每解决一个问题都会使你获得进步)。
“就在你认为你已经成功跨越了一个藩篱时,你与另外一个障碍不期而遇。但这就是生活的奇妙之处。[…]
生活就是一个不断突破桎梏的过程 —— 这是一些我们成长必须突破的阻碍。
每次,你都会获取新知。
每次,你都会变得更加强壮有力,睿智深邃和洞察非凡。
每次,都会有一些挑战被你逾越,从而消失。直到最后所留下的:是那个最好的你。” —— Ryan Holiday (绝境逢生的艺术 (The Obstacle is the Way))
从现在开始,去解决一些问题吧!
祝你好运 🙂
关于本文
译者:@mingxing47
译文:
https://github.com/xitu/gold-miner/blob/master/TODO1/how-to-think-like-a-programmer-lessons-in-problem-solving.md(掘金翻译计划)
作者:@Richard Reis
原文:
https://medium.freecodecamp.org/how-to-think-like-a-programmer-lessons-in-problem-solving-d1d8bf1de7d2
最后,为你推荐
【第1312期】Node.js开发之父:十个Node.js的设计错误以及其终极解决办法